package com.wr.controller.user;

import com.google.common.collect.Maps;
import com.wr.cmmon.CommonConstants;
import com.wr.cmmon.UserContext;
import com.wr.config.FtpConfig;
import com.wr.model.RestCode;
import com.wr.model.RestResponse;
import com.wr.model.ResultMsg;
import com.wr.model.User;
import com.wr.service.MailServiceImpl;
import com.wr.service.user.UserService;
import com.wr.util.FtpUtil;
import com.wr.utils.AccountValidatorUtil;
import com.wr.utils.CommonUtil;
import com.wr.utils.UploadUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private MailServiceImpl mailService;

    private String sessionCode = "user:register:code";

    private String sessionLoginCode = "user:login:code";
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    private FtpConfig ftpConfig;

    private Logger logger = Logger.getLogger(this.getClass());

    @RequestMapping("toLogin")
    public String toLogin(Model model,HttpServletRequest request) {
        if(!isLog()) {
            return "redirect:/";
        }
        String retUrl = request.getHeader("Referer");
        model.addAttribute("retUrl",retUrl);
        return "login/login";
    }

    @RequestMapping("toRegister")
    public String toRegister() {
        if(!isLog()) {
            return "redirect:/";
        }
        return "login/register";
    }

    @PostMapping("loginSubmit")
    @ResponseBody
    public HashMap<String,Object> loginSubmit(HttpServletRequest request, HttpServletResponse response, HttpSession session, User user) {
        HashMap<String,Object> msg = Maps.newHashMap();
        if(StringUtils.isBlank(user.getPassword())) {
            msg.put("code",1);
            msg.put("msg","密码错误");
            return msg;
        }
        if(StringUtils.isBlank(user.getEmail()) || !AccountValidatorUtil.checkEmail(user.getEmail())) {
            msg.put("code",1);
            msg.put("msg","邮箱错误");
            return msg;
        }
        String valicode = request.getParameter("valicode");
        if(StringUtils.isBlank(valicode)) {
            msg.put("code",1);
            msg.put("msg","验证码为空");
            return msg;
        }
        String key = "user:login:valicode:"+session.getId();
        String sesionCode = String.valueOf(redisTemplate.opsForValue().get(key));
        if(!valicode.equals(sesionCode)) {
            msg.put("code",1);
            msg.put("msg","验证码不正确");
            return msg;
        }

        if(userService.getUserByEmail(user.getEmail()).getResult() == null) {
            msg.put("code",1);
            msg.put("msg","邮箱"+user.getEmail()+"未注册，请先注册再登录");
            return msg;
        }
        RestResponse<User> rest = userService.authLogin(user);
        if(rest.getCode() == RestCode.OK.code) {
            User u = rest.getResult();
            UserContext.setUser(u);

            setCookie(response,request,u);
            redisTemplate.delete(key);
            msg.put("code",0);
            msg.put("msg","成功");
            return msg;
        }
        else {
            msg.put("code",1);
            msg.put("msg","登录失败,检查密码是否正确");
            return msg;
        }

    }

    @RequestMapping(value = "registerSubmit",method =RequestMethod.POST)
    @ResponseBody
    public HashMap<String,Object> registerSubmit(HttpServletRequest request, User user) {
        HashMap<String,Object> msg = Maps.newHashMap();
        String code = request.getParameter("code");
        if(StringUtils.isBlank(code)) {
            msg.put("code",1);
            msg.put("msg","验证码不能为空");
            return msg;
        }
        String sessionId = request.getSession().getId();
        String sessionKey = sessionCode+":"+sessionId;
        String valCode =String.valueOf(redisTemplate.opsForValue().get(sessionKey));
        if(!code.equals(valCode)) {
            msg.put("code",1);
            msg.put("msg","验证码不正确");
            return msg;
        }

        ResultMsg retMsg = UserHelper.validate(user);
        if(retMsg.isSuccess()) {

            if(userService.getUserByEmail(user.getEmail()).getResult() != null){
                msg.put("code",1);
                msg.put("msg","邮箱"+user.getEmail()+"已经注册过");
                return msg;
            }
            if(userService.getUserByUserName(user.getUsername()).getResult() != null){
                msg.put("code",1);
                msg.put("msg","用户名"+user.getUsername()+"已经存在");
                return msg;
            }
            long ip = CommonUtil.getIp(request);
            user.setIp(ip);
            RestResponse<User> restResponse = userService.register(user);

            if (restResponse.getCode() == RestCode.OK.code) {
                msg.put("code",0);
                msg.put("msg","注册成功，去登录吧！");
                //删除验证码，验证码只能用一次
                redisTemplate.delete (sessionKey); //验证码5分钟过期时间
                return msg;
            }
            else {
                msg.put("code",0);
                msg.put("msg","内部错误，联系客服!");
                return msg;
            }
        }
        else {
            msg.put("code",1);
            msg.put("msg",retMsg.getErrorMsg());
            return msg;
        }
    }

    @RequestMapping(value = "getCode", method = RequestMethod.POST)
    @ResponseBody
    public Integer getCode(String email, HttpServletRequest request) {
        Integer c = 0;
        if (StringUtils.isNotBlank(email)) {
            String code = CommonUtil.getRandomCode();
            String content = "注册验证码："+ code;
            mailService.sendSimpleMail("Ron网",content,email);
            String sessionId = request.getSession().getId();
            redisTemplate.opsForValue().set(sessionCode+":"+sessionId, code,5, TimeUnit.MINUTES); //验证码5分钟过期时间
            return c;
        }
        c = 1;
        return c;
    }

    @RequestMapping("logout")
    public String logout(HttpServletRequest request,HttpServletResponse response ) {

        User u = UserContext.getUser();
        if(u != null) {
            userService.logout(u.getToken());
            setCookie(response,request,u);
        }
        return "redirect:/";
    }

    private void setCookie(HttpServletResponse response , HttpServletRequest request, User user) {
        String requestURI = request.getRequestURI();

        if (user != null && StringUtils.isNoneBlank(user.getToken())) {
            String token = requestURI.startsWith("logout")? "" : user.getToken();
            Cookie cookie = new Cookie(CommonConstants.TOKEN_COOKIE, token);
            cookie.setPath("/");
            cookie.setHttpOnly(true);
            response.addCookie(cookie);
        }
    }

    private boolean isLog() {
        User user = UserContext.getUser();
        if (user == null) {
            return true;
        }
        return false;
    }

    @RequestMapping("toResetPw")
    public String toResetPw() {

        return "/login/resetpw";
    }

    @PostMapping("resetPw")
    @ResponseBody
    public HashMap<String,Object> resetPw(String oldpassword,String newpassword,String repassword) {
        HashMap<String,Object> map = Maps.newHashMap();

        if(StringUtils.isBlank(oldpassword) || StringUtils.isBlank(newpassword) || StringUtils.isBlank(repassword)) {
            map.put("code",1);
            map.put("msg","数据不能为空");
            return map;
        }
        if(newpassword.length() < 6) {
            map.put("code",1);
            map.put("msg","密码长度不能小于6位");
            return map;
        }
        if(!newpassword.equals(repassword)) {
            map.put("code",1);
            map.put("msg","两次密码输入不一致");
            return map;
        }
        User us = UserContext.getUser();
        User u = new User();
        u.setPassword(oldpassword);
        u.setEmail(us.getEmail());
        RestResponse<User> rest = userService.authLogin(u);
        if(rest.getCode() != RestCode.OK.code) {
            map.put("code",1);
            map.put("msg","原密码错误");
            return map;
        }
        User user = new User();
        user.setId(us.getId());
        user.setPassword(newpassword);
        RestResponse<User> restResponse = userService.resetPw(user);
        if(restResponse.getCode() != RestCode.OK.code) {
            map.put("code",1);
            map.put("msg","重置失败");
            return map;
        }
        map.put("code",0);
        map.put("msg","重置成功,退出重新登录");
        return map;
    }

    @RequestMapping(value="upImg",method= RequestMethod.POST)
    @ResponseBody
    public String upImg(MultipartFile picture, HttpServletRequest request) {

        if (picture!=null && picture.getOriginalFilename()!=null && picture.getOriginalFilename().trim().length()>0) {


            String oldName = picture.getOriginalFilename();// 获取图片原来的名字
            String picNewName = UploadUtils.generateRandonFileName(oldName);// 通过工具类产生新图片名称，防止重名
            String picSavePath = UploadUtils.generateRandomDir(picNewName);// 通过工具类把图片目录分级

            try {
                //图片上传服务器，返回地址
                String avatar = FtpUtil.pictureUploadByConfig(ftpConfig, picNewName, picSavePath, picture.getInputStream());
                User user = UserContext.getUser();
                User u = new User();
                u.setId(user.getId());
                u.setAvatar(avatar);
                user.setAvatar(avatar);
                UserContext.setUser(user);
                userService.update(u);
                return avatar;// 上传到图片服务器的操
            } catch (IOException e) {
                logger.error(e,e);
            }

        }
        return "false";
    }

}
